/*******************************************************************************
 * Copyright 2010 MoBrite (A venture of Kinara Systems Private Limited)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/
package com.mobrite.domaindroid.activity;

import java.util.Date;

import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.mobrite.domaindroid.Constants;
import com.mobrite.domaindroid.DomainDroidException;
import com.mobrite.domaindroid.DomainStatus;
import com.mobrite.domaindroid.R;
import com.mobrite.domaindroid.db.DomainDroidDbAdapter;
import com.mobrite.domaindroid.util.Logger;
import com.mobrite.domaindroid.util.RegistrarHelper;
import com.mobrite.domaindroid.util.UiHelper;
import com.mobrite.domaindroid.util.Util;
import com.mobrite.domaindroid.util.WhoisUtil;
import com.mobrite.domaindroid.whoisparser.WhoisResponseParser;

/*
 * spawn task for each lookup in onCreate
 * in getView(), query task, show progress bar if running, otherwise result info
 */
public class ResultListActivity extends ListActivity implements OnItemClickListener {

	String[] tldList;
	String domain;
	//HashMap<String, String> whoisData = new HashMap<String, String>();
	
	// Menu Ids
	static final int MENU_ID_ADD_TO_FAVOURITES 	= 1;
	static final int MENU_ID_DELETE 				= 2;
	static final int MENU_ID_LOOKUP_AGAIN		 	= 3;
	static final int MENU_ID_PREFS			 	= 4;
	static final int MENU_ID_ABOUT			 	= 5;
	static final int MENU_ID_OPEN_IN_BROWSER	 	= 6;
	static final int MENU_ID_REGISTER			 	= 7;
	static final int MENU_ID_VIEW_WHOIS_DATA 	= 8;

	DomainDroidDbAdapter dbHelper;
	
	//UI
	ListView listView;
	DomainResultListAdapter listAdapter;
	UiHelper uiHelper;
	
	int[] statusList;
	String[] whoisData;
	long[] dbIds;
	
	int finishCount = 0; // Incremented after each lookup task finishes
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.result_list);
		
		tldList = getIntent().getStringArrayExtra(Constants.EXTRA_TLDLIST);
		domain = getIntent().getStringExtra(Constants.EXTRA_DOMAIN);
		
		statusList = new int[tldList.length];
		whoisData = new String[tldList.length];
		dbIds = new long[tldList.length];
		
		for (int i=0; i<statusList.length; i++) {
			statusList[i] = -1; //Initial value
		}
		
		dbHelper = new DomainDroidDbAdapter(this);
		dbHelper.open();
		
		listView = getListView();
		listAdapter = new DomainResultListAdapter(this);
		setListAdapter(listAdapter);
		
		registerForContextMenu(listView);
		listView.setOnItemClickListener(this);
		listView.setItemsCanFocus(false);
		uiHelper = new UiHelper(this);
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		super.onConfigurationChanged(newConfig);
	}
	
	@Override
	protected void onDestroy() {
		dbHelper.close();
		super.onDestroy();
	}
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
		if (-1 == statusList[info.position]) {
			return;
		}
		menu.setHeaderTitle(domain+"."+tldList[info.position]);
		menu.add(0, MENU_ID_VIEW_WHOIS_DATA, 0, R.string.menu_whois);
		menu.add(0, MENU_ID_ADD_TO_FAVOURITES, 0, R.string.menu_favorite);
		if (DomainStatus.UNAVAILABLE==statusList[info.position]) {
			menu.add(0, MENU_ID_OPEN_IN_BROWSER, 0, R.string.menu_openInBrowser).setIntent(new Intent(Intent.ACTION_VIEW,
					Uri.parse("http://"+domain+"."+tldList[info.position])));
			
		}
		else if (DomainStatus.AVAILABLE==statusList[info.position]) {			
			menu.add(0, MENU_ID_REGISTER, 0, R.string.menu_register);
//			.setIntent(new Intent(Intent.ACTION_VIEW,
//					Uri.parse("http://www.enom.com/domainsearch/register.aspx?sld="+domain+"&tld="+tldList[info.position])));			
		}

	}
	
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		final AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();

		switch (item.getItemId()) {

		case MENU_ID_ADD_TO_FAVOURITES:
			if (dbHelper.setFavorite(domain + "." + tldList[info.position],
					tldList[info.position], true)) {
				Toast.makeText(
						this,
						domain + "." + tldList[info.position]
								+ " added to favorites", Toast.LENGTH_LONG)
						.show();
			} else {
				Toast.makeText(
						this,
						"Sorry, " + domain + "." + tldList[info.position]
								+ " could not be added to favorites",
						Toast.LENGTH_LONG).show();
			}
			return true;

		case MENU_ID_VIEW_WHOIS_DATA:
			// Toast.makeText(this, "WHOIS: "+tldList[info.position],
			// Toast.LENGTH_LONG).show();
			viewWhois(info.position);
			return true;

		case MENU_ID_REGISTER:
			uiHelper.showRegistrarList(new DialogInterface.OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					Intent i = new Intent(Intent.ACTION_VIEW, Uri
							.parse(RegistrarHelper.getRegisterUrlForDomain(
									which,
									domain,
									tldList[info.position])));
					startActivity(i);
				}
			});

			return true;

		default:
			return super.onContextItemSelected(item);
		}
	}
	
	private void viewWhois(int position) {
		  Intent intent = new Intent(this, WhoisDataDisplayActivity.class);
		  intent.putExtra(Constants.EXTRA_WHOISDATA, whoisData[position]);
		  intent.putExtra(Constants.EXTRA_DOMAIN, domain+"."+tldList[position]);
		  startActivity(intent);		
	}
	
	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		if (statusList[position]==DomainStatus.AVAILABLE || statusList[position]==DomainStatus.UNAVAILABLE) {
			viewWhois(position);
		}
	}
		
	class DomainResultListAdapter extends BaseAdapter implements DomainListItemViewCallback {

		Context context;
		
        private Drawable mFavoriteIconOn;
        private Drawable mFavoriteIconOff;

		public DomainResultListAdapter(Context context) {
//			super(context, R.layout.search_result_item);
			this.context = context;
			
			Resources resources = context.getResources();
            mFavoriteIconOn = resources.getDrawable(R.drawable.btn_star_big_buttonless_dark_on);
            mFavoriteIconOff = resources.getDrawable(R.drawable.btn_star_big_buttonless_dark_off);
		}
		
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			Logger.d("getView() called. position = "+position+", statusList[position] = "+statusList[position]);

			View row = convertView;

			if (row == null) {
				Logger.d("ResultListActivity", "getView(): covertView is null");
                LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = vi.inflate(R.layout.search_result_item, null);
			}

			if (-1==statusList[position]) {
                new DomainCheckTask(position).execute();				
			}
			
			DomainListItem itemView = (DomainListItem) row;
			itemView.viewInit(this, false);
			
            itemView.domain = domain;
            itemView.tld = tldList[position];
            itemView.id = dbIds[position];
            itemView.whoisResponse = whoisData[position];
            
            TextView mDomain;
            TextView mStatus = (TextView) itemView.findViewById(R.id.TextView02);
			mDomain = (TextView) row.findViewById(R.id.domain);
            mDomain.setText(domain+"."+tldList[position]);            
		
			ProgressBar progressBar = (ProgressBar) itemView.findViewById(R.id.ProgressBar01);			
			ImageView favoriteStar = (ImageView) itemView.findViewById(R.id.favorite);

            switch (statusList[position]) {
			case DomainStatus.AVAILABLE:
	            mStatus.setText("AVAILABLE");
	            //mStatus.setTextColor(Color.rgb(0,150,10));
	            mStatus.setTextColor(getResources().getColor(R.color.available));
				progressBar.setEnabled(false);
				progressBar.setVisibility(View.INVISIBLE);
				favoriteStar.setVisibility(View.VISIBLE);
//	            itemView.setTag("A");
//	            itemView.id = dbHelper.addDomain(domain+"."+tld, tld, true, date.getTime());
				break;
				
			case DomainStatus.UNAVAILABLE:
	            mStatus.setText("TAKEN");				
	            mStatus.setTextColor(getResources().getColor(R.color.taken));
				progressBar.setEnabled(false);
				progressBar.setVisibility(View.INVISIBLE);
				favoriteStar.setVisibility(View.VISIBLE);
//	            mStatus.setTextColor(getResources().getColor(R.color.taken));
//	            itemView.id = dbHelper.addDomain(domain+"."+tld, tld, false, date.getTime());
				break;
				
			case DomainStatus.ERROR:
				progressBar.setEnabled(false);
				progressBar.setVisibility(View.INVISIBLE);
				favoriteStar.setVisibility(View.INVISIBLE);
	            mStatus.setText("Network Error, Please Try Again");				
	            mStatus.setTextColor(Color.DKGRAY);
				break;
				
			case DomainStatus.UNSUPPORTED_TLD:
				progressBar.setEnabled(false);
				progressBar.setVisibility(View.INVISIBLE);
	            mStatus.setText("This TLD is not supported yet");				
	            mStatus.setTextColor(Color.DKGRAY);
				favoriteStar.setVisibility(View.INVISIBLE);

				break;

			default:
				mStatus.setText("Checking Availability...");
				mStatus.setTextColor(Color.WHITE);
				progressBar.setEnabled(false);
				progressBar.setVisibility(View.VISIBLE);
				favoriteStar.setVisibility(View.INVISIBLE);
				break;
			}

			return row;
			
			//return super.getView(position, convertView, parent);
		}

		@Override
		public int getCount() {
			return tldList.length;
		}

		@Override
		public Object getItem(int position) {
			Logger.d("ResultListActivity", "getItem() called");
			return null;
		}

		@Override
		public long getItemId(int position) {
			Logger.d("ResultListActivity", "getItemId() called");
			return position;
		}

		public void updateFavorite(DomainListItem domainResultListItem,
				boolean mFavorite) {

			ImageView favoriteView = (ImageView) domainResultListItem.findViewById(R.id.favorite);
            favoriteView.setImageDrawable(mFavorite ? mFavoriteIconOn : mFavoriteIconOff);

			if (domainResultListItem.id>=0) {
				dbHelper.setFavorite(domainResultListItem.id, mFavorite);
			}
			else {
				dbHelper.setFavorite(domainResultListItem.domain+"."+domainResultListItem.tld, domainResultListItem.tld, mFavorite);
			}
		}
		
		public void updateSelected(DomainListItem domainListItem,
				boolean mSelected) {
			// Do nothing
		}

	}
	

	class DomainCheckTask extends AsyncTask<Void, Void, Integer> {

		//DomainListItem itemView = null;
		String tld = null;
		int position;
		
		public DomainCheckTask(int position) {
			this.position = position;
		}
		
		@Override
		protected void onPreExecute() {
            //TextView mStatus = (TextView) itemView.findViewById(R.id.TextView02);
            //mStatus.setText("Checking Availability...");        
		}
		
		@Override
		protected Integer doInBackground(Void... params) {

			//int index = params[0].intValue();
			tld = tldList[position];
			if (!WhoisUtil.WHOIS_SERVERS.containsKey(tld)) return DomainStatus.UNSUPPORTED_TLD;
			try {
				String response = WhoisUtil.getWhoisData(WhoisUtil.WHOIS_SERVERS.getProperty(tld), domain+"."+tld);
				//whoisData.put(tld, response);
				whoisData[position] = response;
				WhoisResponseParser parser = WhoisUtil.getWhoisResponseParserForTld(tld);
				return parser.isAvailable(response, domain) ? DomainStatus.AVAILABLE : DomainStatus.UNAVAILABLE;

				//return WhoisUtil.checkAvailability(domain, tld) ? DomainStatus.AVAILABLE : DomainStatus.UNAVAILABLE;
			} catch (DomainDroidException e) {
				return DomainStatus.ERROR;
			}
			
		}

		@Override
		protected void onPostExecute(Integer result) {
			
            Date date = new Date();

            statusList[position] = result.intValue();
            	
            switch (result.intValue()) {
			case DomainStatus.AVAILABLE:
	            //itemView.setTag("A");
	            dbIds[position] = dbHelper.addDomain(domain+"."+tld, tld, true, date.getTime());
				break;
				
			case DomainStatus.UNAVAILABLE:
	            dbIds[position] = dbHelper.addDomain(domain+"."+tld, tld, false, date.getTime());
				break;
				
			case DomainStatus.ERROR:
				break;
				
			case DomainStatus.UNSUPPORTED_TLD:
				break;

			default:
				break;
			}
                       
            listAdapter.notifyDataSetChanged();
            finishCount++;
            if (finishCount==tldList.length) {
            	Toast.makeText(ResultListActivity.this, "Long-click an item for more options", Toast.LENGTH_LONG).show();
            }
		}				
		
	}

}
